<html>
<head>
<title>NoMoSmooth</title>
<link rel="stylesheet" type="text/css" href="../../avisynth.css">
</head>

<body bgcolor="#FFFFFF" text="#000000">
<h1>NoMoSmooth</h1>
<h2>Abstract</h2>
<b>author:</b> Sansgrip (Ross Thomas)<br>
<b>version:</b>  0.1b<br>
<b>download:</b>&nbsp;<a href="http:/www.avisynth.org/warpenterprises/">http://www.avisynth.org/warpenterprises/</a><br>
<b>category:</b>  Spatio-Temporal Smoothers&nbsp;<br>
<b>requirements:</b>  YUY2 Colorspace
<hr>
<h2>Description</h2>
<p>When it comes to smoothers (as opposed to smoothies) there are two main varieties:
  temporal smoothers and spatial smoothers. Temporal smoothers work by looking
  at frames surrounding the current one and averaging corresponding pixels together
  if they're deemed similar enough (and thus likely to be noise). Spatial smoothers
  work in a similar way, except they look at nearby pixels within the same frame.
  A few filters are a hybrid of the two, including this one and the excellent
  Convolution3D.</p>
<p>Each approach has its advantages and disadvantages. The great thing about temporal
  smoothers is that they do a fantastic job getting rid of noise when you set
  them up just right, but they can also generate some very ugly artifacts, particularly
  when dealing with motion. Spatial smoothers, on the other hand, can be quite
  destructive to the details in your image, but are great with high-motion areas
  because those have few details and are moving too quickly to notice artifacts
  anyway.</p>
<p>Ideally, then, one would like to apply a temporal smoother to relatively static
  areas and a spatial smoother to moving ones. That's what this filter tries to
  do, and the aim is for a higher quality result (i.e. less noticible smoothing)
  than Convolution3D but with correspondingly less of an impact on compressibility.</p>
<p>In addition to this motion-based approach, NoMoSmooth employs another technique
  to try to retain as much existing detail as possible: only pixels that are &quot;fluctuating&quot;
  are smoothed. In other words, given three frames in a row with the current one
  in the centre, the pixel being examined will only be considered for either type
  of smoothing if it is either greater than both the corresponding pixels in the
  previous and next frames, or less than both. This could be considered a very
  simplistic &quot;noise detector&quot; and seems to help reduce temporal smoothing
  on important details such as those in skin tones.</p>
<h2>Usage</h2>
<blockquote>
  <p><code>NoMoSmooth</code> (<var>clip, int &quot;motion_threshold&quot;, int
  &quot;temporal_radius&quot;,
    int &quot;temporal_threshold&quot;, int &quot;spatial_radius&quot;, int
  &quot;spatial_threshold&quot;,
    bool &quot;show&quot;</var>)</p>
</blockquote>
<table border="1">
  <tr>
    <th>Parameter</th>
    <th>Meaning</th>
    <th>Default</th>
  </tr>
  <tr>
    <td><var>motion_threshold</var></td>
    <td>
      <p>Controls how sensitive the motion detector is to, er, motion, with lower
        values being more sensitive (seeing more motion) and higher being less
        sensitive. I might go into the algorithm in more detail in a later version
        of this file, but for now if you're curious look at the source.</p>
    </td>
    <td>40</td>
  </tr>
  <tr>
    <td><var>temporal_radius</var></td>
    <td>Determines how far the temporal smoother will venture into the clip to
      do its work. If set to 2 a total of 5 frames are examined, 2 on each &quot;side&quot;
      of the current one.</td>
    <td>1</td>
  </tr>
  <tr>
    <td><var>temporal_threshold</var></td>
    <td>When the temporal smoother is averaging it will only include values within
      this threshold of the pixel in the current frame.</td>
    <td>6</td>
  </tr>
  <tr>
    <td><var>spatial_radius</var></td>
    <td>Determines how many pixels the spatial smoother will consider when doing
      it's job. If set to 2 a total of 25 pixels are examined, with the current
      pixel in the centre.</td>
    <td>1</td>
  </tr>
  <tr>
    <td><var>spatial_threshold</var></td>
    <td>The spatial smoother will only include values within this threshold when
      it is averaging.</td>
    <td>3</td>
  </tr>
  <tr>
    <td><var>show</var></td>
    <td>If true no smoothing will be carried out, but areas deemed to be in motion
      (according to the <i>motion_threshold</i> parameter) will be highlighted
      in a charming light grey.</td>
    <td>false</td>
  </tr>
</table>
<h2>Known Issues</h2>
<ul>
  <li>Pixels within <i>spatial_radius</i> of the edges get passed through.</li>
  <li>Frames within <i>temporal_radius</i> of the ends of the clip get passed
    through. </li>
  <li>While the algorithm is fairly well optimized it's still fairly slow, but
    very brief tests indicate it might be slightly faster than Convolution3D in
    preset=&quot;movieHQ&quot; mode.</li>
</ul>
<h2>CopyRight</h2>
<p>There is no copyright on this code, and there are no conditions on its distribution
  or use. Do with it what you will.</p>
<h2>TODO</h2>
<ul>
  <li>Optimize both algorithmically and by implementing assembly code versions
    of critical parts of the algorithm.</li>
  <li>Improve motion detector such that it is more sensitive to motion in low-contrast
    areas. </li>
</ul>
<h2>Author</h2>
<p>Ross Thomas &lt;ross at grinfinity.com&gt;</p>
<h2>History</h2>
<table border="1">
  <tr>
    <th>Version</th>
    <th>Description</th>
  </tr>
   <tr>
    <td>0.1b</td>
    <td>Compiled for AviSynth v2.5 by Wilbert. [YUY2 required!]
  </td>
  </tr>
  <tr>
    <td>0.1a</td>
    <td>Fixed off-by-one error that caused an access violation when height &gt;
      462.</td>
  </tr>
  <tr>
    <td>0.1</td>
    <td>Total rewrite with a number of algorithmic improvements, much more verbose
      comments and widespread use of assertions. Made brief preparations for an
      eventual YV12 version. Implemented &quot;noise detector&quot;. First official
      (yet still alpha) release. </td>
  </tr>
  <tr>
    <td>0.0c</td>
    <td>Back on track. Rewrote again, this time making a conscious effort not
      to duplicate code already in the core. Implemented a motion detector so
      that areas in motion get spatially softened and static areas get softened
      temporally. The name &quot;NoMoSmooth&quot; makes less sense every time
      I read it.</td>
  </tr>
  <tr>
    <td>0.0b</td>
    <td>Highly embarrassing version algorithmically identical to TemporalSoften
      which must never be spoken of again.</td>
  </tr>
  <tr>
    <td>0.0a</td>
    <td>Rewrote from scratch and optimized the algorithm somewhat, so now is slightly
      faster. A change in the algorithm both removed the need for <i>noise_threshold</i>
      and made <i>show</i> mode extremely difficult to implement.</td>
  </tr>
  <tr>
    <td> 0.0</td>
    <td>Proof of concept code. Hard hats must be worn in this area.</td>
  </tr>
</table>
<p><kbd>$Date: 2005/10/03 16:31:31 $</kbd></p>
</body>
</html>
